package com.thghh.dcross;

import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.*;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;

import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        Map<String, Object> settings = new HashMap<>();
        // settings.put(Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
        settings.put(Environment.DIALECT, determineDatabaseDialectClass(Database.MYSQL));
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(settings).build();
        MetadataImplementor metadata = (MetadataImplementor) new MetadataSources(serviceRegistry).buildMetadata();
        metadata.validate();

        final SchemaExport schemaExport = new SchemaExport();

        // create w/o dropping first; (OK because tables don't exist yet
        schemaExport.execute( EnumSet.of( TargetType.DATABASE ), SchemaExport.Action.CREATE, metadata );

        // create w/o dropping again; should cause an exception because the tables exist already
        schemaExport.execute( EnumSet.of( TargetType.DATABASE ), SchemaExport.Action.CREATE, metadata );

        // drop tables only
        schemaExport.execute( EnumSet.of( TargetType.DATABASE ), SchemaExport.Action.DROP, metadata );
    }

    /**
     * Determine the Hibernate database dialect class for the given target database.
     * @param database the target database
     * @return the Hibernate database dialect class, or {@code null} if none found
     */
    protected static Class<?> determineDatabaseDialectClass(Database database) {
        switch (database) {
            case DB2: return DB2Dialect.class;
            case DERBY: return DerbyTenSevenDialect.class;
            case H2: return H2Dialect.class;
            case HANA: return HANAColumnStoreDialect.class;
            case HSQL: return HSQLDialect.class;
            case INFORMIX: return Informix10Dialect.class;
            case MYSQL: return MySQL8Dialect.class;
            case ORACLE: return Oracle12cDialect.class;
            case POSTGRESQL: return PostgreSQL95Dialect.class;
            case SQLSERVER: return SQLServer2012Dialect.class;
            case SYBASE: return SybaseDialect.class;
            default: return null;
        }
    }
}
